<?php
require_once ('odal/meta/namespace.php');
require_once ('odal/meta/omsmetadata.php');

/**
 * @author <a href="mailto:vs@brixlent.de">brixlent - Volker Schubert</a> TODO:
 * comment
 * @version 1.0
 * @created 03-Aug-2004 21:09:05
 */
class odal_OMSData{
	var $m_connectionAlias;
	var $m_datasource;
	var $m_metaData;
	var $m_aCatName = array();
	var $m_userId = null;
	var $m_newIndex = 0;
	var $NEWINDEX_STEP = 1000000;
	var $RESOURCE_NAMESPACE = 'odal.oracle';
	var $ROOT_ATTRIBUTE= 'objects';
	var $m_bInited = false; 


	/**
	 * @param resourcePath
	 * @param connectionAlias
	 * @exception OMSResourceException OMSResourceException
	 */
	function odal_OMSData( $resourcePath = null, $connectionAlias = null, $userId = null  ){
		//echo "[omsdata->odal_OMSData] this->m_bInited: " . $this->m_bInited . "<br>\n";
		if ( $resourcePath != null && $connectionAlias != null ){
			$this->init( $resourcePath, $connectionAlias, $userId );
		}//if
	}//odal_OMSData
	
	function init( $resourcePath, $connectionAlias, $userId ){
		//echo "[omsdata->init] this->isInited(): *" . $this->isInited() . "* - userId: *" . $userId ."*<br>\n";
		if ( !$this->isInited() ){
			//echo "[omsdata->init] <br>\n";
			$this->m_connectionAlias = $connectionAlias;
			
			$oConnMgr = createObject( $resourcePath, 'connectionManager');
			$this->m_datasource =& $oConnMgr->getConnection( $connectionAlias );
			//print_r( $this->m_datasource );
			if ( $this->m_datasource == null ){
				trigger_error( "[omsdata->odal_OMSData] Could not connect to database with resourcePath '" . $resourcePath . "' and connectionAlias '" . $connectionAlias . "'" );
			}//if
			$dsn = $this->m_datasource->getConnectionData();
			$this->RESOURCE_NAMESPACE = 'odal.'.$dsn['phptype'];
			$this->m_userId = $userId;
			$this->m_metaData =& new odal_OMSMetaData( $this );
			$this->m_bInited = true;
		}//if
	}//init
	
	function isInited(){
		return $this->m_bInited;
	}//isInited
	
	function &getConnectionAlias(){
		return $this->m_connectionAlias;
	}//getConnectionAlias

	function &getMetaData(){
		return $this->m_metaData;
	}//getMetaData
		

	/**
	 * Returns the <code>DataSource</code> instance which this object is associated
	 * with.
	 * @return DataSource
	 */
	function &getDataSource(){
		return $this->m_datasource;
	}//getDataSource

	/**
	 * Returns new <code>OMSStructure</code> instance.
	 * @return OMSStructure
	 * @param whereStr    - select criteria
	 * @exception OMSResourceException OMSResourceException
	 */
	function &getOMSStructureByWhere( $whereStr, $p_aSelectedJoins = array() ){
		$aSqlParams[ 'noass' ] = '';
		$aSqlParams[ 'nobvl' ] = '';
		$aSqlParams[ 'nocvl' ] = '';
		$aSqlParams[ 'nosvl' ] = '';
		$aSqlParams[ 'nouvl' ] = '';
		$index = array_search( 'noass', $p_aSelectedJoins );
		if ( $index === 0 || $index > 0 ){
			$aSqlParams[ 'noass' ] = '--';
		}//if
		$index = array_search( 'nobvl', $p_aSelectedJoins );
		if ( $index === 0 || $index > 0 ){
			$aSqlParams[ 'nobvl' ] = '--';
		}//if
		$index = array_search( 'nocvl', $p_aSelectedJoins );
		if ( $index === 0 || $index > 0 ){
			$aSqlParams[ 'nocvl' ] = '--';
		}//if
		$index = array_search( 'nosvl', $p_aSelectedJoins );
		if ( $index === 0 || $index > 0 ){
			$aSqlParams[ 'nosvl' ] = '--';
		}//if
		$index = array_search( 'nouvl', $p_aSelectedJoins );
		if ( $index === 0 || $index > 0 ){
			$aSqlParams[ 'nouvl' ] = '--';
		}//if
		$aSqlBindvars[ 'p_cursor' ] = '__cursor';
		$aSqlParams[ 'wherestr' ] = $whereStr;
		$aSqlParams[ 'asswherestr' ] = '';
		$aSqlParams[ 'bvlwherestr' ] = '';
		$aSqlParams[ 'cvlwherestr' ] = '';
		$aSqlParams[ 'svlwherestr' ] = '';
		$aSqlParams[ 'uvlwherestr' ] = '';
		return $this->_getOmsStructure( $aSqlParams, $aSqlBindvars, 'getomsstructurebywhere', null );
	}//getOMSStructureByWhere
	
	function &getOMSStructureByResource( $resourceName, $placeHolders, $bindVariables, $namespace = null, $resetCache = false ){
			##################################################################
			$bench = &singleton_Singleton::getInstance('benchmark_CubeBenchmark');
			$bench->start('getOMSStructureByResource');
			##################################################################
		$omsStructure =& $this->_getOmsStructure( $placeHolders, $bindVariables, $resourceName, $namespace, $resetCache );
			##################################################################
			$count = 0;
			if($omsStructure != null)
				$count = count($omsStructure->getElements());
			$bench->stop('getOMSStructureByResource',array('ElementsCount' => $count));
			##################################################################
		return $omsStructure;
	}//getOMSStructureByResource

	function &_getOmsStructure( $aSqlParams, $aSqlBindvars, $resource, $namespace = null, $resetCache = false ){
		$aResult = $this->executeOnResource( $resource, $aSqlParams, $aSqlBindvars, $namespace, $resetCache );
		if ( ( $aResult != null ) && ( count( $aResult[0] ) > 0 ) ){
			$omsStructure =& new odal_OmsStructure( $this->getUserId(), $this->getNewIndex() );
			$this->_createElementsInStructure( $omsStructure, $aResult[0] );
		}//if
		return $omsStructure;
	}//_getOmsStructure
	
	function &_reloadAssociations2Structure( &$p_oOmsStucture, $aSqlParams, $aSqlBindvars, $resource, $namespace = null, $resetCache = false ){
		$aResult =& $this->executeOnResource( $resource, $aSqlParams, $aSqlBindvars, $namespace, $resetCache );
		if ( ( $aResult != null ) && ( count( $aResult[0] ) > 0 ) ){
			foreach( $aResult[0] as $aRow ) {
				$this->_addAssoc2Structure( $aRow, $p_oOmsStucture );
			}//foreach
			$p_oOmsStucture->_pck_buildRelations();
		}//if
		return $p_oOmsStucture;
	}//_reloadAssociations2Structure
	
	function reloadAssociations2StructureByWhere( &$p_oOmsStucture, $p_where ) {
		$aSqlBindvars[ 'p_cursor' ] = '__cursor';
		$aSqlParams[ 'wherestr' ] = $p_where;
		return $this->_reloadAssociations2Structure( $p_oOmsStucture, $aSqlParams, $aSqlBindvars, 'reloadassociationsbywhere', null );
	}//reloadAssociations2StructureByWhere
	
	function reloadAssociations2StructureByResource( &$p_oOmsStucture, $resourceName, $placeHolders, $bindVariables, $namespace = null, $resetCache = false ) {
		return $this->_reloadAssociations2Structure( $p_oOmsStucture, $placeHolders, $bindVariables, $resourceName, $namespace );
	}//reloadAssociations2StructureByResource

	function getNewIndex(){
		$this->m_newIndex += $this->NEWINDEX_STEP;
		return $this->m_newIndex;
	}//getNewIndex

	function _createElementsInStructure( &$omsStructure, &$aElements ){
		$bench = &singleton_Singleton::getInstance('benchmark_CubeBenchmark');
		$bench->start('_createElementsInStructure');
		$bench->start('createElements');
		foreach( $aElements as $aElement ){
			//echo "(omsdata->_createElementsInStructure): target " . $aElement['CMP_TARGET_ELM_ID'] . " - source: " . $aElement['CMP_SOURCE_ELM_ID'] . " - cat_id: " . $aElement['CMP_CAT_ID'] . " - cmp_id: " .  $aElement['CMP_ID'] . "<br>";
			unset( $oElement );
			unset( $oScheme );
			$oElement =& $omsStructure->getElementById( $aElement['ELM_ID'] );
			if ( $oElement == null ){ 
//				$bench->start('getScheme');
				$oScheme =& $this->m_metaData->getSchemeById( $aElement['ELM_SCM_ID'] );
				if ( $oScheme == null ) {
					$oScheme =& $this->m_metaData->createMetaDataBySchemeId( $aElement['ELM_SCM_ID'], false );
				}//if
//				$bench->stop('getScheme');
				$schemeName = $oScheme->getName();
//				$bench->start('getNamespace');
				$oNamespace =& $oScheme->getNamespace();
//				$bench->stop('getNamespace');
				$namespacePath = $oNamespace->getPath();  
				$oElement =& new odal_Element( $omsStructure, $aElement['ELM_ID'], $aElement['ELM_DISPLAYNAME'], $aElement['ELM_BOOKMARK'], $schemeName, $namespacePath, $aElement['ELM_CREATINGDATE'], $aElement['ELM_CREATING_ELM_ID'], $aElement['ELM_MODIFYINGDATE'], $aElement['ELM_MODIFYING_ELM_ID']);
				$omsStructure->_pck_appendElement2Structure( $oElement ); 
				$parent = $aElement['CMP_SOURCE_ELM_ID'];
				if ( $parent == null ) {
					$parent = 0;
				}//if
				$oElement->setParentElementId( $parent );
				$oElement->_pck_setCompositionKey( $aElement['CMP_KEY'] );
				//save relation data for composition
				$catName = $this->_getCatName( $aElement['CMP_CAT_ID'] );
				$omsStructure->_pck_addCmp( $aElement['CMP_TARGET_ELM_ID'], $aElement['CMP_SOURCE_ELM_ID'], $catName, $aElement['CMP_ID'] , $aElement['CMP_KEY'], $aElement['CMP_SIBLING_ORDER'], $aElement['CMP_PATH'], $aElement['CMP_LEVEL'] ) ;
			}//if
			$this->_createValues( $omsStructure, $aElement );
			$this->_addAssoc2Structure( $aElement, $omsStructure );
		}//foreach
		$bench->stop('createElements');
		$omsStructure->_pck_buildRelations( );
		//echo "(omsdata->_createElementsInStructure) E N D E<br><br>";  
		$bench->stop('_createElementsInStructure');
	}//_createElementsInStructure
	
	function _addAssoc2Structure( &$p_aRow, &$p_oOmstructure ) {
		if ( isset( $p_aRow['ASS_TARGET_ELM_ID'] ) && $p_aRow['ASS_TARGET_ELM_ID'] != null ){
			$catName = $this->_getCatName( $p_aRow['ASS_CAT_ID'] );
			$p_oOmstructure->_pck_addAssoc( $p_aRow['ASS_TARGET_ELM_ID'], $p_aRow['ASS_SOURCE_ELM_ID'], $catName, $p_aRow['ASS_ID'], $p_aRow['ASS_KEY'], $p_aRow['ASS_SIBLING_ORDER'] );
		}//if
	}//_addAssoc2Structure
	
	function _createValues( &$omsStructure, $aElement ){
		if ( isset( $aElement['SVL_ID']) && ( $aElement['SVL_ID'] != null ) ) {
			$this->_createValue4Element( $omsStructure, $aElement, 's' );
		}//if
		if ( isset( $aElement['UVL_ID']) && ( $aElement['UVL_ID'] != null ) ) {
			$this->_createValue4Element( $omsStructure, $aElement, 'u' );
		}//if
		if ( isset( $aElement['CVL_ID']) && ( $aElement['CVL_ID'] != null ) ) {
			$this->_createValue4Element( $omsStructure, $aElement, 'c' );
		}//if
		if ( isset( $aElement['BVL_ID']) && ( $aElement['BVL_ID'] != null ) ) {
			$this->_createValue4Element( $omsStructure, $aElement, 'b' );
		}//if
	}//_createValues


	function _getCatName( $catId ){
		if ( $catId == null ){
			//special treatment for root
			$catName =  $this->ROOT_ATTRIBUTE;
		} else {
			if ( isset( $this->m_aCatName[ $catId ] ) ){
				$catName = $this->m_aCatName[ $catId ];
			} else {
				//echo '_gatCatName: ' . $catId . "\n";
				$this->_pck_setSchemeMetaDataByCatId( $catId );
				$oComplexattribute =& $this->m_metaData->getComplexattributeById( $catId );
				$catName = $oComplexattribute->getName();
				$this->m_aCatName[ $catId ] = $catName;
			}//else
		}//else
		return $catName; 
	}//getCatName
	
	
	function _createValue4Element( &$omsStructure, $aElement, $type ){
		$upperType = strtoupper( $type );
//		echo "[omsdata->_createValue4Element] upperType: " . $upperType . "<br>\n";
		$vl_id = $aElement[$upperType . 'VL_ID'];
		//echo "[omsdata->_createValue4Element] vl_id: " . $vl_id . "<br>\n";
		$elm_id = $aElement[$upperType . 'VL_ELM_ID'];
		$oElement =& $omsStructure->getElementById( $aElement[$upperType . 'VL_ELM_ID'] );
		$oScheme =& $this->m_metaData->getScheme( $oElement->getNamespacePath(), $oElement->getSchemeName() );
		$oSimpleAttribute =& $oScheme->getSimpleAttributeById( $aElement[$upperType . 'VL_SAT_ID'] );
		$oDatatype =& $oSimpleAttribute->getDatatype( );
		$oDatatypeEnumeration =& $oDatatype->getDatatypeEnumerationById( $aElement[$upperType . 'VL_DEN_ID'] );
		$oValue =& $oElement->getValueObject( $oSimpleAttribute->getName(), $oDatatypeEnumeration->getName() );
		if ( $oValue == null ){
			//echo "[omsdata->_createValue4Element] oValue->getName: " . $oValue->getName . "<br>\n";
			//echo "[omsdata->_createValue4Element] elm_id: " . $elm_id . "<br>\n";
			$oElement->_pck_createValue( $oSimpleAttribute->getName(), $oDatatypeEnumeration->getName(), $aElement[$upperType . 'VL_VALUE'], $aElement[$upperType . 'VL_ID'] );
		}//if
	}//_createValue4Element

//******************************* BEGIN Save *****************************************//
	function &_getNodes2Save( &$omsStructure ){
//		require_once( 'odal/xmlvisualizer.php' );
//		$xMLVisualizer =& new odal_XMLVisualizer( $omsStructure );
//		$xml = $xMLVisualizer->getOmsStructureAsXML();
//		echo $xml;
		
		$aRetNodes = Array();
		$this->_recurseNodes4Save( $omsStructure->getRootElement(), $aRetNodes ); 
		$this->_recurseNodes4Save( $omsStructure->getTrashElement(), $aRetNodes ); 
		//Values under Trash
		$oTrash =& $omsStructure->getTrashElement();
		foreach ( $oTrash->getValues() as $tmpVal ){
			unset( $value );
			$oValue =& $oTrash->getValueByIdAndType( $tmpVal->getId(), $tmpVal->getType() );
			$this->_addNodes2Save( $aRetNodes, $oValue, $oValue->getType(), $oTrash->getId() ); 
		}//foreach
		return $aRetNodes;
	}//_getNodes2Save
	
	function _recurseNodes4Save( &$p_element, &$aRetNodes ){
		//Element
		$this->_addNodes2Save( $aRetNodes, $p_element, "e", null );
		//Values
		$this->_addValues2Save( $p_element, $aRetNodes );
		//Relations
		$aRelations = $p_element->_pck_getRelations();
		foreach ( $aRelations as $catName => $dummy2 ){
//			echo "[omsdata->_recurseNodes4Save] cat_name: " . $catName . "<br>\n";
//			echo "[omsdata->_recurseNodes4Save] p_element->getName(): " . $p_element->getName() . "<br>\n";
			unset( $oRelation );
			$oRelation =& $p_element->_pck_getRelationByComplexAttributeName( $catName );
			if ( $oRelation->_pck_isAssociation() ){
				$this->_addAssociations2Save( $p_element, $oRelation, $aRetNodes );
			} else {
//				echo "[omsdata->_recurseNodes4Save] Composition! <br>\n";
				unset( $targetVector );
				$targetVector =& $oRelation->_pck_getTargets();
				while ( $target =& $targetVector->_pck_each() ){
					unset( $targetElement );
					$targetElement =& $target->_pck_getElement();
					$this->_recurseNodes4Save( $targetElement, $aRetNodes );
				}//while
			}//else
		}//foreach
	}//_recurseNodes4Save
	
	function _addValues2Save( &$p_element, &$aRetNodes ){
		foreach ( $p_element->getValues() as $satName => $aSat ){
			foreach ( $aSat as $denName => $tmpVal ){
				unset( $value );
				$value =& $p_element->getValueObject( $satName, $denName );
				//echo "<br>[omsdata->_getNodes2Save] checking values - content: " . $value->getContent() . " - satName: " . $satName . " - denName . " . $denName . "<br>\n";
				//echo "[omsdata->_getNodes2Save] value->_pck_getState() : " . $value->_pck_getState()  . "<br>\n";
				$this->_addNodes2Save( $aRetNodes, $value, 'v', $p_element->getId() ); 
			}//foreach
		}//foreach
	}//_addValues2Save

	function _addAssociations2Save( &$p_element, &$oRelation, &$aRetNodes ){
		$targetVector =& $oRelation->_pck_getTargets();
		while ( $target =& $targetVector->_pck_each() ){
			$state = $target->_pck_getState();
			$relId = $target->_pck_getRelationId();
			$catName = $oRelation->_pck_getCatName();
			unset( $targetElement );
			unset( $aAssoc );
			$targetElement =& $target->_pck_getElement();
			//echo "[omsdata->_addAssociations2Save] targetElement->getName(): " . $targetElement->getName() . "<br>";
			//echo "(omsdata->_addAssociations2Save) relId: " . $target->_pck_getRelationId() . " - state: " . $target->_pck_getState() . " - p_element->getId(): " .  $p_element->getId() . "<br>\n";
			//echo "(omsdata->_addAssociations2Save) relId: " . $relId . " - state: " . $state . " - p_element->getId(): " .  $p_element->getId() . " - targetElement->getId(): " .  $targetElement->getId() .  "<br>";
			//move_association_before
			if ( $state == 4 ){
				//echo "[omsdata->_addAssociations2Save] target->_pck_getRelationId():" .  $target->_pck_getRelationId() . "<br>"; 								
				//echo "[omsdata->_addAssociations2Save] vor getprevious. <br>"; 								
				$beforeTarget =& $targetVector->_pck_getCurrent();
				//print_r($beforeTarget);
				$relIdBefore = $beforeTarget->_pck_getRelationId();
				//echo "[omsdata->_addAssociations2Save] target->_pck_getRelationId():" .  $target->_pck_getRelationId() . "<br>"; 								
				//echo "[omsdata->_addAssociations2Save] relIdBefore: $relIdBefore . <br>"; 								
				$targetVector->_pck_setCurrent( $target );
				$aAssoc = Array( $p_element->getId(),  $relIdBefore, $catName, $relId, $state );
			//move_association_append 
			}elseif ( $state == 5 ){
				//echo "[omsdata->_addAssociations2Save] target->_pck_getRelationId():" .  $target->_pck_getRelationId() . "<br>"; 
				//echo "[omsdata->_addAssociations2Save] p_element->getSchemeName():" .  $p_element->getSchemeName() . "<br>"; 
				//echo "[omsdata->_addAssociations2Save] p_element->getNamespacePath():" .  $p_element->getNamespacePath() . "<br>"; 
				$oMetaData =& $this->getMetaData();
				$oScheme =& $oMetaData->getScheme( $p_element->getNamespacePath(), $p_element->getSchemeName() );							
				$oCat =& $oScheme->getComplexAttributeByName( $catName );							
				$aAssoc = Array( $p_element->getId(), $oCat->getId(), $catName, $relId, $state );
			}else{
				$aAssoc = Array( $p_element->getId(),  $targetElement->getId(), $catName, $relId, $state );
			}//else
			//echo "[omsdata->_addAssociations2Save] sourceElement-Id: " . $aAssoc[0] . "<br>" ;
			$this->_addNodes2Save( $aRetNodes, $aAssoc, 'a', $p_element->getId() ); 
		}//while
	}//_addAssociations2Save

	function _addNodes2Save( &$aNodes, &$etNode, $type, $foreignId = null ){
		//Values and Element
		if ( !( strpos( 've', $type ) === false ) ){
			$state = $etNode->_pck_getState();
		//Association
		}elseif( $type = 'a' ){
			$state = $etNode[4];
		}//elseif
//		echo "(omsdata->_addNodes2Save) state: " . $state . "<br>\n";
		if (  $state > 0 ){
//			if (  ( $type == "e" ) || ( $type == "v" )  ){
//				echo "(omsdata->_addNodes2Save)  etNode->getId(): " . $etNode->getId() . " - etNode->getName(): " . $etNode->getName() . "<br>\n";
//				echo "(omsdata->_addNodes2Save) etNode->_pck_getState(): " . $etNode->_pck_getState() . "<br>\n*************<br>\n";
//			}//if
			$aNode = array();
			$aNode[0] = $type;
			$aNode[1] =& $etNode;
			$aNode[2] = $foreignId;
			$aNodes[] = $aNode;
		}//if
	}//_addNodes2Save

	/**
	 * Saves the given element tree into the database.
	 * @return OMSStructure - tree updated while saving
	 * @param tree    - tree to save
	 * @exception OMSResourceException OMSResourceException
	 */
	function saveOmsStructure( &$omsStructure, $commit = true ){
		if ( $omsStructure->getUserId() === null ){
			trigger_error( '[omsdata->saveOmsStructure] User-Id in given structure not set!' );
		}//if
		$bRet = true;
		$aNodes =& $this->_getNodes2Save( $omsStructure );
//		echo "[omsddata->saveOmsStructure] count( aNodes ): " . count( $aNodes ) . "<br>";
		if ( $aNodes != null ){
			$bRet = $this->_save( $omsStructure, $aNodes );
		}//if
		if ( $bRet and $commit ){
			$this->commit();
		}//if
		return $bRet; 
	}//saveOmsStructure

	function _save( &$omsStructure, $aNodes ){
		$bOk = true;
		$conn =& $this->getDataSource();
		$conn->setAutoCommit( false );
		$aNewIds = Array();
		$aStatements = Array();
		$i = 0;
		$j = 0;
		$start = 0;

		//echo "(omsddata->_save) vor delete Associations <br>";
		if ( $bOk ){
			//manipulate Associations
			foreach ( $aNodes as $aNode ){
				if ( ( $aNode[0] == 'a' ) && ($aNode[1][4] > 1 ) ){
					$this->_appendStatement4Association( $omsStructure, $aNode[1], $aStatements, $aNode[2] );
					$i++;
					//echo "(omsdata->_save) manipulate association <br>";
				}//if
			}//foreach
			$start = $this->_executeSQL( $aStatements, $start, $i, $bOk );
		}//if

		//echo "(omsddata->_save) vor Elements <br>";
		if ( $bOk ){
			//Elements
			foreach ( $aNodes as $aNode ){
				if ( $aNode[0] == 'e' ){
					$this->_appendStatement4EtNode( $omsStructure, $aNode[1], $aStatements, $aNode[0], null );
					$i++;
				}//if
			}//foreach
			for( $j = $start; $j < $i; $j++ ){
				$nodeId = $aStatements[$j][1];
				$retval = $this->_executeSave4Node( $aStatements[$j][3], $aNewIds );
//				echo "(omsstructure->_save) aStatements[$j][3]: "; print_r( $aStatements[$j][3] ); echo "<br>\n";
				//echo "(omsstructure->_save) retval: " . $retval . "<br>";
				if ( $retval > 0 ){
					$aStatements[$j]['newid'] = $retval;
					if ( substr( $nodeId, 0, 3 ) == 'new' ){
						$aNewIds[$nodeId] = $retval;
					}//if
				}else{
					$bOk = false;
					break;
				}//else
			}//for
			$start = $j;
		}//if

		//echo "(omsddata->_save) vor Values <br>";
		if ( $bOk ){
			//Values
			foreach ( $aNodes as $aNode ){
				if ( $aNode[0] === 'v' ){
					//echo "(omsdata->_save  - Values ) aNode[2]: " . $aNode[2] . "<br>";
					//echo "(omsdata->_save  - Values ) aNode[1]->getName(): " . $aNode[1]->getName() . "<br>";
					$foreignId = $aNode[2];
					//echo "(omsdata->_save  - Values ) aNode[2]: " . $aNode[2] . "<br>";
					if ( substr( $foreignId, 0, 3 ) == 'new' ){
						$foreignId = $aNewIds[$foreignId]; 
					}//if
					$this->_appendStatement4EtNode( $omsStructure, $aNode[1], $aStatements, $aNode[0], $foreignId );
					$i++;
				}//if
			}//foreach
			$start = $this->_executeSQL( $aStatements, $start, $i, $bOk );
		}//if

		//echo "(omsddata->_save) new Associations<br>";
		if ( $bOk ){
			//new Associations
			foreach ( $aNodes as $aNode ){
				if ( ( $aNode[0] == 'a' ) && ($aNode[1][4] == 1 ) ){
					if ( substr( $aNode[1][0], 0, 3 ) == 'new' ){
						$aNode[1][0] = $aNewIds[$aNode[1][0]]; 
					}//if
					if ( substr( $aNode[1][1], 0, 3 ) == 'new' ){
						$aNode[1][1] = $aNewIds[$aNode[1][1]]; 
					}//if
					$this->_appendStatement4Association( $omsStructure, $aNode[1], $aStatements, $aNode[2] );
					$i++;
				}//if
			}//foreach
			$start = $this->_executeSQL( $aStatements, $start, $i, $bOk );
		}//if
		//echo "(omsddata->_save) nach allen Statements - bOk: $bOk<br>";
		
		if ( $bOk ){
			$omsStructure->_pck_refresh( $aStatements );
			$omsStructure->_pck_clearTrash();
		}//if
		
		return $bOk;
	}//_save
	
	function _executeSQL( &$aStatements, $start, $max, &$bOk ){
		for( $j = $start; $j < $max; $j++ ){
			//echo "<br>(omsdata->_executeSQL) aStatements[$j][3]:";
			//print_r( $aStatements[$j][3] );
			//echo "<br>";
			$newId = $this->_executeSave4Node( $aStatements[$j][3], null );
			//echo "(omsdata->_executeSQL) newId: ". $newId . " - oldId:" . $aStatements[$j][1] .  " - type:" . $aStatements[$j][0] . " - state:" . $aStatements[$j][1] . "<br><br>";
			//echo "(omsdata->_executeSQL) aStatements[$j][3]: " . $aStatements[$j][3] . "<br>";
			//echo "(omsdata->_executeSQL) newId: $newId<br>";
			if ( $newId > 0 ){
				$aStatements[$j]['newid'] = $newId ;
			}//if
//			else{
//				$bOk = false;
//				break;
//			}//else
		}//for
		return $j;
	}//_executeSQL
		
	function _appendStatement4EtNode( &$omsStructure, &$etNode, &$aStatements, $type, $foreignId = null ){
		$aStmt = Array();
		$aStmt['bindvars'] = Array( 'retval' => null );
		//echo "(omsdata->_appendStatement4EtNode) etNode->_pck_getState(): " . $etNode->_pck_getState() . "<br>";
		//echo "(omsdata->_appendStatement4EtNode) etNode->getName(): " . $etNode->getName() . "<br>";
		switch ( $etNode->_pck_getState() ){
			case 1: //new
				if ( $type == 'e' ){
					$scheme =& $this->m_metaData->getScheme( $etNode->getNamespacePath(), $etNode->getSchemeName() ); 
					//echo "(omsdata->_appendStatement4EtNode) scheme->getId(): " . $scheme->getId() . "<br>";
					$parentElement = $omsStructure->getElementById( $etNode->getParentElementId() );
					$catName = $parentElement->_pck_getCompositionComplexAttributeNameByTargetElement( $etNode );
					//echo "(omsdata->_appendStatement4EtNode) new element - parentElement->getName(): " . $parentElement->getName() . "<br>";
					$schemeParent =& $this->m_metaData->getScheme( $parentElement->getNamespacePath(), $parentElement->getSchemeName() );
					if ( $schemeParent == null ){
						trigger_error( "[omsdata->_appendStatement4EtNode] Error on save Element! Could not determine Scheme of parentElement for NamespacePath '" . $parentElement->getNamespacePath() . "' and SchemeName '" . $parentElement->getSchemeName() . "'" );
					}//if
					$oCat = $schemeParent->getComplexAttributeByName( $catName );
					if ( $oCat == null ){
						trigger_error( "[omsdata->_appendStatement4EtNode] Error on save Element! Could not determine Complex Attribute for Scheme: '" . $schemeParent->getName() . "' and Complex Attribute: '" . $catName . "'"  );
					}//if
					//$name = str_replace ( "\'", "''", $etNode->getName() );
					$name = $this->m_datasource->sqlescape( $etNode->getName() );
					$bookmark = $this->_getValue4bookmarkOrKey( $this->m_datasource->sqlescape( $etNode->getBookmark() ) );
					$key = $this->_getValue4bookmarkOrKey( $this->m_datasource->sqlescape( $etNode->_pck_getCompositionKey() ) );
					$aStmt['params'] = Array( 'displayname' => "'".$name."'", 'bookmark' => $bookmark, 'scm_id' => $scheme->getId(), 'key' => $key, 'source_elm_id' => $etNode->getParentElementId(), 'source_cat_id' => $oCat->getId(), 'creater_id' => $omsStructure->getUserId() );
					$aStmt['resource'] = 'create_element'; 
				}elseif( $type == 'v' ){
					//$element =& $omsStructure->getElementById( $foreignId );
					$element =& $etNode->getElement();
					if ( $element == null ){
						trigger_error( "[omsdata->_appendStatement4EtNode] Error on save Value! Could not determine Element for Id '" . $foreignId . "'" );
					}//if
					$scheme =& $this->m_metaData->getScheme( $element->getNamespacePath(), $element->getSchemeName() ); 
					if ( $scheme == null ){
						trigger_error( "[omsdata->_appendStatement4EtNode] Error on save Value! Could not determine Scheme for NamespacePath '" . $element->getNamespacePath() . "' and SchemeName '" . $element->getSchemeName() . "'" );
					}//if
					$oSimpleAttribute =& $scheme->getSimpleAttributeByName( $etNode->getSimpleAttributeName() );
					if ( $oSimpleAttribute == null ){
						trigger_error( "[omsdata->_appendStatement4EtNode] Error on save Value! Could not determine SimpleAttribute for '" . $etNode->getSimpleAttributeName() . "'" );
					}//if
					//echo "[omsdata->_appendStatement4EtNode] oSimpleAttribute->getName(): " . $oSimpleAttribute->getName() . "<br>\n";
					$oDatatype =& $oSimpleAttribute->getDatatype();
					$oDatatypeEnumeration =& $oDatatype->getDatatypeEnumerationByName( $etNode->getDatatypeEnumerationName() );
					if ( $oDatatypeEnumeration == null ){
						trigger_error( "[omsdata->_appendStatement4EtNode] Error on save Value! Could not determine DatatypeEnumeration for '" . $etNode->getDatatypeEnumerationName() . "'" );
					}//if
					$valueType = $this->_getValueType( $element, $etNode );
					$content = $etNode->getContent();
					if( !( strpos( 'csu', $valueType ) === false ) ){
						$content = $this->m_datasource->sqlescape( $content );
					}//if
					if ( $valueType == 'b' ){
						$aStmt['resource'] = 'create_blobvalue'; 
					}elseif ( $valueType == 'c' ){
						$aStmt['resource'] = 'create_clobvalue'; 
					}elseif ( $valueType == 's' ){
						$aStmt['resource'] = 'create_simplevalue'; 
					}elseif ( $valueType == 'u' ){
						$aStmt['resource'] = 'create_uniquevalue'; 
					}//elseif
					$aStmt['params'] = Array( 'content' => "'".$content."'", 'elm_id' => $foreignId, 'sat_id' => $oSimpleAttribute->getId(), 'den_id' => $oDatatypeEnumeration->getId(), 'creater_id' => $omsStructure->getUserId() );
				}//elseif
				break;
    		case 2: //update
    			if ( $type == 'e' ){
					$name = str_replace ( "'", "''", $etNode->getName() );
					$bookmark = $this->_getValue4bookmarkOrKey( $this->m_datasource->sqlescape( $etNode->getBookmark() ) );
					$aStmt['params'] = Array( 'id' => $etNode->getId(), 'displayname' => "'".$name."'", 'bookmark' => $bookmark, 'modifier_id' => $omsStructure->getUserId() );
					$aStmt['resource'] = 'update_element'; 
				}elseif(  $type === 'v' ){
					$content = $etNode->getContent();
					$valueType = $this->_getValueType( $etNode->getElement(), $etNode );
					if( !( strpos( 'csu', $valueType ) === false ) ){
						$content = $this->m_datasource->sqlescape( $content );
					}//if
					if ( $valueType == 'b' ){
						$aStmt['resource'] = 'update_blobvalue'; 
					}elseif ( $valueType == 'c' ){
						$aStmt['resource'] = 'update_clobvalue'; 
					}elseif ( $valueType == 's' ){
						$aStmt['resource'] = 'update_simplevalue'; 
					}elseif ( $valueType == 'u' ){
						$aStmt['resource'] = 'update_uniquevalue'; 
					}//elseif
					$aStmt['params'] = Array( 'id' => $etNode->getId(), 'value' => "'".$content."'", 'modifier_id' => $omsStructure->getUserId() );
    			}//elseif
        		break;
    		case 3: //delete
				$aStmt['params'] = Array( 'id' => $etNode->getId() );
    			if ( $type == 'e' ){
					$aStmt['resource'] = 'remove_element'; 
				}elseif( $type = 'v' ){
					$valueType = $this->_getValueType( $etNode->getElement(), $etNode );
					if ( $valueType == 'b' ){
						$aStmt['resource'] = 'remove_blobvalue'; 
					}elseif ( $valueType == 'c' ){
						$aStmt['resource'] = 'remove_clobvalue'; 
					}elseif ( $valueType == 's' ){
						$aStmt['resource'] = 'remove_simplevalue'; 
					}elseif ( $valueType == 'u' ){
						$aStmt['resource'] = 'remove_uniquevalue'; 
					}//elseif
    			}//elseif
        		break;
		}//switch
		$aDetails = array(); 
		$aDetails[0] = $type;
		$aDetails[1] = $etNode->getId();
		$aDetails[2] =& $etNode;
		$aDetails[3] =& $aStmt;
		$aDetails['state'] = $etNode->_pck_getState();
		$aDetails['foreignid'] = $foreignId;
		$aStatements[] =& $aDetails;
	}//_appendStatement4EtNode

	function _getValue4bookmarkOrKey( $val ){
		if ( $val == null || ( substr( $val, 0, 4 ) == 'new_' ) ){
			$val = 'null';
		} else {
			$val = "'" . $val . "'";
		}//else
		return $val;
	}//_getValue4bookmarkOrKey

	function _getValueType( &$element, &$value ){
		$scheme =& $this->m_metaData->getScheme( $element->getNamespacePath(), $element->getSchemeName() ); 
		$oSimpleAttribute =& $scheme->getSimpleAttributeByName( $value->getSimpleAttributeName() );
		return $oSimpleAttribute->getValueType();
	}//_getValueType

	function _appendStatement4Association( &$omsStructure, $aAssoc, &$aStatements, $sourceElmId ){
		//echo "(omsdata->_appendStatement4Association) aAssoc:<br>";
		//echo "<br>";
		//$stmt = "begin :retval:=";
//		$aStmt["bindvars"] = Array( "retval" => null );
		$aStmt["bindvars"] = array();
		switch ( $aAssoc[4] ){
			case 1: //new
				$aStmt["bindvars"] = Array( "retval" => null );
				$source =& $omsStructure->getElementById( $sourceElmId );
//				echo "[omsdata->_appendStatement4Association] sourceElement-Id: " . $sourceElmId . "<br>" ;
				$sourceScheme =& $this->m_metaData->getScheme( $source->getNamespacePath(), $source->getSchemeName() );
				$oCat =& $sourceScheme->getComplexAttributeByName( $aAssoc[2] );
				if ( $oCat == null ){
					trigger_error("[omsdata->_appendStatement4Association] '" . $aAssoc[2] . "' is no valid association name for scheme '" . $sourceScheme->getName() . "'" );
				}//if 
				$catId = $oCat->getId();
				$aStmt["params"] = Array( "source_elm_id" => $aAssoc[0], "cat_id" => $oCat->getId(), "target_elm_id" => $aAssoc[1], "key" => "null", "creater_id" => $omsStructure->getUserId());
				$aStmt["resource"] = "append_association"; 
       			//$stmt = $stmt . " pck_relation.appendAssociation(" . $aAssoc[0] . "," . $aAssoc[2] . "," . $aAssoc[1] . ",null," . $omsStructure->getUserId() . ");";
				break;
			case 3: //delete
				$aStmt["bindvars"] = Array( "retval" => null );
				$aStmt["params"] = Array( "id" => $aAssoc[3] );
				$aStmt["resource"] = "remove_association"; 
				//$stmt = $stmt . " pck_relation.removeAssociation(" . $aAssoc[3] . ");"; 
				break;
			case 4: //move before
				$aStmt["params"] = Array( "ass_id" => $aAssoc[3], "before_ass_id" => $aAssoc[1], "modifier_id" => $omsStructure->getUserId());
				$aStmt["resource"] = "move_association_before"; 
				//$stmt = $stmt . " pck_relation.removeAssociation(" . $aAssoc[3] . ");"; 
				break;
			case 5: //move append
				$aStmt["params"] = Array( "ass_id" => $aAssoc[3], "source_elm_id" => $aAssoc[0], "cat_id" => $aAssoc[1], "modifier_id" => $omsStructure->getUserId() );
				$aStmt["resource"] = "move_association_append"; 
				//$stmt = $stmt . " pck_relation.removeAssociation(" . $aAssoc[3] . ");"; 
				break;
		}//switch
		//echo "(omsdata->_appendStatement4Association) stmt(: " . count( $aStatements ) . ")" . $stmt . "<br>";
		//echo "(omsstructure->_appendStatement4Association) id: " . $aAssoc[3] . " - state: " . $aAssoc[4] . "<br>";
		$aStatements[] = Array( 'a', $aAssoc[3], $aAssoc,  $aStmt, 'state' => $aAssoc[4] );
//		echo "(omsdata->_appendStatement4Association) aStmt: <br>";
//		print_r( $aStmt );
//		echo "<br>";
	}//_appendStatement4Association
	
	function _executeSave4Node( $aStmt, $aNewIds ){
		//print_r( $aStmt );
		//$aSqlBindvars['retval'] = null;
		//$conn->executeProcedure( $stmt, $aSqlBindvars );
		//$conn->executeProcedure( $stmt, $aSqlBindvars );
		//echo "***"; print_r($aNewIds); echo "****<br>";
		if ( isset( $aStmt['params']['source_elm_id'] ) ){
			if ( substr( $aStmt['params']['source_elm_id'],0,3) == 'new' ){
				$aStmt['params']['source_elm_id'] = $aNewIds[$aStmt['params']['source_elm_id']];
			}//if
		}//if
		$this->executeOnResource( $aStmt['resource'], $aStmt['params'], $aStmt['bindvars'] );
//		echo '(OMSData->_executeSave4Node) stmt: ' . $stmt . '<br>';
//		echo '(OMSData->_executeSave4Node) aSqlBindvars['retval']: ' . $aSqlBindvars['retval']. '<br>';
//		echo '(OMSData->_executeSave4Node) aStmt['params']: ';
//		print_r( $aStmt['params'] );
//		echo '<br>';
//		echo '(OMSData->_executeSave4Node) aStmt['resource']: ' . $aStmt['resource'] . '<br>';
//		echo '(OMSData->_executeSave4Node) aStmt['bindvars']['retval']: ' . $aStmt['bindvars']['retval']. '<br>';
//		print_r( $aStmt['bindvars'] );
//		echo '<br>';
		$retId = null;
		if ( isset( $aStmt['bindvars']['retval'] ) ){
			$retId = $aStmt['bindvars']['retval'];
		}//if 
		return $retId;
	}//_executeSave4Node
//******************************* END Save *****************************************//



	/**
	 * Binds the given variables and executes the statement.
	 * @return HashMap[][] - one array for one output cursor from the statement -
	 * single  array contains records as column_name->value maps.
	 * @param resourceFile    - the file with statement to execute
	 * @param placeHolders    - the token to replace withing the statement
	 * @param bindVariables    - variables to bind
	 * @exception OMSResourceException OMSResourceException
	 */
	function executeOnResource( $resourceFile, $placeHolders, &$bindVariables, $namespace = null, $resetCache = false ){
//		echo "[omsdata->executeOnResource] resourceFile: " . $resourceFile . "<br>/n";
		$conn =& $this->getDataSource();
		if ( $conn == null ){
			trigger_error( "[omsdata->executeOnResource] Database connection is not set!");
		}//if
		if ( $namespace == null ){
			$namespace = $this->RESOURCE_NAMESPACE;
		}//if 
		return $conn->executeOnResource( $placeHolders, $bindVariables, $resourceFile, $namespace, $resetCache );
	}//executeOnResource
	
	function commit(){
		$conn =& $this->getDataSource();
		$conn->commit();
	}//commit
	
	
	function getUserId(){
		return $this->m_userId;
	}//getUserId

	function setUserId( $p_userId ){
		$this->m_userId = $p_userId;
	}//setUserId
		
	function &_setNamespaceMetaDataFromDB( $nsp_key, $type ){
		$aSqlParams['nsp_key'] = $nsp_key;
		$aSqlParams['nsp_type'] = $type;
		$aSqlBindvars['p_cursor'] = '__cursor';
		$aResult = $this->executeOnResource( "getnamespacemetadatabynamespaceid", $aSqlParams, $aSqlBindvars );
		$aMetaDatas = $aResult[0];
		$nsp_id = 0;
		$dat_id = 0;
		foreach( $aMetaDatas as $aMetaData ){
			//Namespace	
			if ( $aMetaData['NSP_ID'] !=  $nsp_id ){
				$nsp_id = $aMetaData['NSP_ID'];
				unset( $oNamespace );
//				$oNamespace =& $this->m_metaData->getNamespaceById( $nsp_id );
//				if ( $oNamespace == null ){
					$oNamespace =& new odal_Namespace( $nsp_id, $aMetaData['NSP_NAME'], $aMetaData['NSP_PATH'], $aMetaData['NSP_CREATINGDATE'], $aMetaData['NSP_CREATING_ELM_ID'], $aMetaData['NSP_MODIFYINGDATE'], $aMetaData['NSP_MODIFYING_ELM_ID'] );
					$this->m_metaData->appendNamespace( $oNamespace );
//				}//if
			}//if
			//Datatype
			if ( $aMetaData['DAT_ID'] !=  $dat_id ){
				$dat_id = $aMetaData['DAT_ID'];
			}//if
			if ( ( $dat_id != null ) ){
				unset( $oDatatype );
				$oDatatype =& $oNamespace->getDatatypeById( $dat_id );
				if ( $oDatatype == null ){
					$oDatatype =& new odal_Datatype( $oNamespace, $dat_id, $aMetaData['DAT_NAME'] , $aMetaData['DAT_TYPE'] ,$aMetaData['DAT_VALUETYPE'] ,$aMetaData['DAT_CREATINGDATE'], $aMetaData['DAT_CREATING_ELM_ID'], $aMetaData['DAT_MODIFYINGDATE'], $aMetaData['DAT_MODIFYING_ELM_ID'] );
					//echo "(omsddata->getNamespaceMetaDataFromDB) aMetaData['DAT_VALUETYPE']: " . $aMetaData['DAT_VALUETYPE'] . "<br>";
					$oNamespace->appendDatatype( $oDatatype );
				}//if
			}//if
			//DatatypeEnumeration
			$den_id = $aMetaData['DEN_ID'];
			if ( ( $den_id != null ) && ( $oDatatype->getDatatypeEnumerationById( $den_id ) == null ) ){
				unset( $oDatatypeEnumeration );
				$oDatatypeEnumeration =& new odal_DatatypeEnumeration( $oDatatype, $den_id, $aMetaData['DEN_VALUE'], $aMetaData['DEN_USE'], $aMetaData['DEN_CREATINGDATE'], $aMetaData['DEN_CREATING_ELM_ID'], $aMetaData['DEN_MODIFYINGDATE'], $aMetaData['DEN_MODIFYING_ELM_ID'] );
				$oDatatype->appendDatatypeEnumeration( $oDatatypeEnumeration );
				//echo "(OMSData->createMetaData4Scheme) oDatatypeEnumeration->getId(): " . $oDatatypeEnumeration->getId() . "<br>";
			}//if
		}//foreach
		if ( $this->m_metaData->_useCache() && ( $oNamespace != null ) ){
			$key = "nsp_" . $nsp_key;
			$this->m_metaData->writeToCache( $oNamespace, $key );
		}//if
		return $oNamespace;
	}//_setNamespaceMetaDataFromDB

	function &_pck_setSchemeMetaDataFromDB( $p_scm_id ){
		$aSqlParams['scm_id'] = $p_scm_id;
		$aSqlBindvars['p_cursor'] = '__cursor';
		$aResult = $this->executeOnResource( "getschememetadatabyschemeid" , $aSqlParams, $aSqlBindvars );
		$oScheme =& $this->_loadSchemeMetaData( $aResult[0], $p_scm_id );
		if ( $this->m_metaData->_useCache() && ( $oScheme != null ) ){
			$key = "scm_" . $p_scm_id;
			$this->m_metaData->writeToCache( $oScheme, $key );
		}//if
		return $oScheme;
	}//_pck_setSchemeMetaDataFromDB
	
	function &_pck_setSchemeMetaDataByCatId( $p_cat_id ){
		//echo "(OMSData->_pck_setSchemeMetaDataByCatId) p_cat_id: " . $p_cat_id . "<br>";
		$scm_id = null;
		if ( $this->m_metaData->_useCache() ){
			$key = "cat_" . $p_cat_id;
			$scm_id =& $this->m_metaData->_getMetaDataFromCache( $this->m_metaData->_getCacheKey( $key ) );
			//echo "[omsdata->_pck_setSchemeMetaDataByCatId] scm_id nach cache: " . $scm_id . "<br>\n";
		}//if
		if ( $scm_id == null ){
			$aSqlParams['cat_id'] = $p_cat_id;
			$aSqlBindvars['scm_id'] = null;
			$aResult = $this->executeOnResource( "getsourceschemeidbycatid" , $aSqlParams, $aSqlBindvars );
			$scm_id = $aSqlBindvars['scm_id'];
			if ( $this->m_metaData->_useCache() && ( $scm_id != null ) ){
				$this->m_metaData->writeToCache( $scm_id, $key );
			}//if
			//echo "[omsdata->_pck_setSchemeMetaDataByCatId] scm_id nach db: " . $scm_id . "<br>\n";
		}//if
		//return $this->_pck_setSchemeMetaDataFromDB(  $aSqlBindvars['scm_id'] );
		return $this->m_metaData->createMetaDataBySchemeId( $scm_id );
	}//_pck_setSchemeMetaDataByCatId

	function &_loadSchemeMetaData( &$aMetaDatas, $p_scm_id ){
		$aSchemes = Array();
		$aSimpleAttributes = Array();
		$aComplexAttributes = Array();
		foreach( $aMetaDatas as $aMetaData ){
			//Namespace
			unset( $oNamespace );
			$nsp_id = $aMetaData['SCM_NSP_ID'];
			$oNamespace =& $this->m_metaData->getNamespaceById( $nsp_id );
			if ( $oNamespace == null){
				//$oNamespace =& $this->_setNamespaceMetaDataFromDB( $nsp_id );
				$oNamespace =& $this->m_metaData->createMetaDataByNamespaceId( $nsp_id );
			}//if
			if ( $oNamespace == null ){
				trigger_error( "[omsdata->_pck_setSchemeMetaDataFromDB] could not get Namespace for id: " . $nsp_id );
			}//if
			//Scheme
			if ( $aMetaData['SCM_ID'] == $p_scm_id ) {
				unset ($oScheme);
				$oScheme =& $this->_buildSchemes($oNamespace, $aMetaData );
			}//if
			//ComplexAttribute
			if ( $aMetaData['CAT_ID'] != null ) {
				//echo "(OMSData->getSchemeMetaDataFromDB) cat_id: $aMetaData[CAT_ID],  CAT_NAME: " . $aMetaData['CAT_NAME'] . "<br>";
				$this->_buildComplexAttributes($aComplexAttributes, $aMetaData, $oScheme);
			}//if
			//SimpleAttribute
			if ( $aMetaData['SAT_ID'] != null ) {
				$this->_buildSimpleAttributes($aSimpleAttributes, $aMetaData);
			}//if
		}//foreach
		$oScheme->setSimpleAttributes( $aSimpleAttributes );
		$oScheme->setComplexAttributes( $aComplexAttributes );
		return $oScheme;
	}//_loadSchemeMetaData
	
	function &_buildSchemes( &$oNamespace, &$aMetaData ){
		$oScheme =& $this->m_metaData->getSchemeById( $aMetaData['SCM_ID'] );
		if ( $oScheme == null ){
			//echo "[omsdata->_buildSchemes()] p_scm_id: " . $aMetaData['SCM_ID'] . "<br>";
			$oScheme =& new odal_Scheme( $oNamespace, $aMetaData['SCM_ID'], $aMetaData['SCM_PARENT_SCM_ID'] ,$aMetaData['SCM_NAME'] , $aMetaData['SCM_CREATINGDATE'], $aMetaData['SCM_CREATING_ELM_ID'], $aMetaData['SCM_MODIFYINGDATE'], $aMetaData['SCM_MODIFYING_ELM_ID'] );
			$oNamespace->appendScheme( $aMetaData['SCM_ID'], $oScheme );
			$oScheme->setNamespace( $oNamespace );
			$aSchemes[$aMetaData['SCM_ID']] =& $oScheme;
			$this->m_metaData->appendScheme( $oScheme );
		}//if
		return $oScheme;
	}//_buildSchemes
	
	function _buildComplexAttributes(&$aComplexAttributes, &$aMetaData, &$oScheme){
		$oComplexAttribute =& $aComplexAttributes[$aMetaData['CAT_ID']];
		if ( $oComplexAttribute == null){
//			echo "(OMSData->_buildComplexAttributes) cat_id: $aMetaData[CAT_ID],  CAT_NAME: " . $aMetaData['CAT_NAME'] . "<br>";
//			echo "(OMSData->_buildComplexAttributes) scheme:" . $oScheme->getName() ."<br>";
			$oComplexAttribute =& new odal_ComplexAttribute( $oScheme, $aMetaData['CAT_TARGET_SCM_ID'], $aMetaData['CAT_MINMULTIPLICITY'], $aMetaData['CAT_MAXMULTIPLICITY'], $aMetaData['CAT_RELATIONTYPE'], $aMetaData['CAT_ID'], $aMetaData['CAT_NAME'] , $aMetaData['CAT_CREATINGDATE'], $aMetaData['CAT_CREATING_ELM_ID'], $aMetaData['CAT_MODIFYINGDATE'], $aMetaData['CAT_MODIFYING_ELM_ID'] );
			$aComplexAttributes[$oComplexAttribute->getId()] =& $oComplexAttribute;
			$this->m_metaData->appendComplexAttribute( $oComplexAttribute );
		}//if 
	}//_buildComplexAttributes
	
	function _buildSimpleAttributes( &$aSimpleAttributes, &$aMetaData ){
		$oSimpleAttribute =& $aSimpleAttributes[$aMetaData['SAT_ID']];
		if ( $oSimpleAttribute == null){
			unset( $oNamespace );
			unset( $oDatatype );
			$oNamespace =& $this->m_metaData->getNamespaceById( $aMetaData['DAT_NSP_ID'] );
			if ( $oNamespace == null){
				//$oNamespace =& $this->_setNamespaceMetaDataFromDB( $aMetaData['DAT_NSP_ID'] );
				$oNamespace =& $this->m_metaData->createMetaDataByNamespaceId( $aMetaData['DAT_NSP_ID'] );
			}//if
			//echo "[omsdata->_buildSimpleAttributes] nspId: " . $aMetaData['DAT_NSP_ID'] . "<br>";
			//echo "[omsdata->_buildSimpleAttributes] sat name: " . $aMetaData['SAT_NAME'] . "<br>";
			$oDatatype =& $oNamespace->getDatatypeById( $aMetaData['SAT_DAT_ID'] );
			$oSimpleAttribute =& new odal_SimpleAttribute( $oScheme, $oDatatype, $aMetaData['SAT_ID'], $aMetaData['SAT_NAME'] , $aMetaData['SAT_CREATINGDATE'], $aMetaData['SAT_CREATING_ELM_ID'], $aMetaData['SAT_MODIFYINGDATE'], $aMetaData['SAT_MODIFYING_ELM_ID'] );
			$aSimpleAttributes[$oSimpleAttribute->getId()] =& $oSimpleAttribute;
		}//if 
	}//_buildSimpleAttributes

}//odal_OMSData
?>